/* Moderator	: helpbygrace ( helpbygrace_AT_gmail.com ) */
/**********************************************************
  Memory Architecture based on Unified Memory

  일반적인 Harvard 구조에서는 Instruction 메모리와 Data
  메모리가 분리되어있다. 그러나 실제로 일반적인 환경에서는
  이 두 메모리는 결국 하나의 BUS를 통해 전체 주소를 공유하
  게 된다.

  BUS 와 각 메모리 interface사이에 캐시가 존재할 수도, 아닐
  수도 있다. 이 부분은 proc_t 구조체에서 캐시 메모리가 정의
  되느냐 아니냐에 따라 달린 부분이고, 일반적인 시스템을 볼
  때 메모리가 통합적인 구조라 가정한다.
  ********************************************************/

#ifndef _MEM_H_
#define _MEM_H_
#include "common.h"
#include "proc.h"

#define MEM_BLOCK	4096	/* byte 단위 4kB */
/*#define	TOTAL_MEM	1024*1024*/
#define	BLOCKS		1024*1024
#define MTAG(ADDR)	(((ADDR) >> 12) & 0xFFFFF)
#define	MIDX(ADDR)	((ADDR) & 0xFFF)
#define MOFFSET(ADDR)	((ADDR) & 0x3)

#define MDATA(TAG,IDX)	(mem->b[TAG]->d[IDX])
/**********************************************************
  mem_block_t
    4kB 단위의 메모리 block이다.
    이 블럭이 모여서 32비트의 총 메모리를 가지게 된다.
    block은 필요할 때에만 할당된다.
  ********************************************************/
typedef struct
{
  u8	d[MEM_BLOCK];	/* 자료가 저장되는 공간 */
  word	offset;			/* 시작번지를 지정할 수 있다.*/
} mem_block_t;

typedef struct
{
  mem_block_t	*b[BLOCKS];	/* memory block list : 포인터배열*/
  	/* (*b)[BLOCKS] 랑은 다르다. 아래는 [BLOCKS] 배열을 참조하는
	   포인터이고, 위는 포인터를 [BLOCKS]개 가지는 배열이다*/
  word	capacity;		/* # of allocated mem_block_t */
  word	limit;			/* maximum block counts limit */
} mem_t;

typedef enum
{
  mem_mode_ld,
  mem_mode_st
} mem_mode_t;

typedef enum
{
  mem_data_ub,
  mem_data_sb,
  mem_data_uh,
  mem_data_sh,
  mem_data_w
} mem_data_t;

void init_mem(mem_t* mem, word limit);
void fini_mem(mem_t* mem);	/* unallocate all memory blocks*/

int	op_mem (proc_t		*proc,
		mem_t		*mem,
		word 		addr,
		mem_mode_t	mode,
		mem_data_t	data,
		word		st,
		word		*ld	);

#endif /* _MEM_H_ */
